﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using DTO;

namespace Publisher_WS
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class PublisherServices : System.Web.Services.WebService
    {
        // doi tuong de truy cap csdl theo ki thuat ADO.net Entities.
        private PublisherDBEntitiesWS dataBaseEntities = new PublisherDBEntitiesWS();    
        private static List<SessionInfo> liveSession = new List<SessionInfo>() ;
        private const int SESSION_LIVE_TIME = 300; // 5 minutes
        private const string SESSIONS = "SESSIONS";
        /// <summary>
        /// Dang nhap vao he thong ws
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [WebMethod]
        public string DangNhap(string username, string password)
        {
            try
            {
                 List<KhachHang> list = dataBaseEntities
                                            .KhachHangs
                                            .Where(kh => kh.TenTaiKhoan == username && kh.MatKhau == password)
                                                .ToList();
                int maKhachHang = list[0].MaKhachHang;
                // kiem tra da dang nhap chua
                List<Session> sessions = dataBaseEntities
                    .Sessions.Where(s => s.MaKhachHang == maKhachHang).ToList();
                if(sessions != null && sessions.Count > 0) // da dang nhap
                {
                    return sessions[0].sID;
                }
                else
                {
                    // tao session id cho lan login nay
                    string sessionId = CommonLib.GenerateId();
                    ThemSession(list[0].MaKhachHang, sessionId);
                    return sessionId;
                }
               
            }
            catch (Exception)
            {
                return null;
            }
           
        }

        /// <summary>
        /// Lay danh sach moi nhat khach hang chua mua
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        [WebMethod]
        public SachDTO[] XemSachMoi(String sID)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                List<int> dsSachDaMua = dataBaseEntities
                    .ChiTietHoaDons
                    .Where(cthd => cthd.HoaDon.MaKhachHang == session.MaKhachHang)
                    .Select(thongtin => thongtin.MaSach)
                    .Distinct()
                    .ToList();
                List<Sach> sachs = dataBaseEntities.Saches.ToList();
                List<int> toanBoSach = new List<int>();
                foreach (Sach sach in sachs)
                {
                    toanBoSach.Add(sach.MaSach);
                }

                
                List<SachDTO> ketQua = new List<SachDTO>();
                foreach (int maSo in toanBoSach)
                {
                    try
                    {
                        if(dsSachDaMua.Where(sachMua => sachMua == maSo).ToList().Count == 0)
                        {
                            SachDTO sachDto = LayThongTinSach(maSo);
                            ketQua.Add(sachDto);    
                        }

                    }
                    catch (Exception)
                    {
                     
                    }
                }
                return ketQua.ToArray();
            }
            else
            {
                return null;
            }
           
        }

        [WebMethod]
        public SachDTO XemChiTietSach(string sID, int maSach)
        {
            try
            {
                SachDTO sachDto = LayThongTinSach(maSach);
                return sachDto;
            }
            catch
            {
                return null;
            }
        }

        
        public SachDTO LayThongTinSach(int maSach)
        {
            try
            {
                Sach sach = dataBaseEntities
                            .Saches
                            .Where(s => (s.MaSach == maSach))
                            .Single();
                SachDTO sachDto = new SachDTO();
                sachDto.MaSach = sach.MaSach;
                sachDto.ConLai = (int)sach.SoLuongCon;
                sachDto.GiaSach = (decimal)sach.GiaSach;
                sachDto.LinkBiaSach = sach.AnhBia;
                sachDto.MoTa = sach.TomTacNoiDung;
                sachDto.NgayXuatBang = (DateTime)sach.NgayXuatBang;
                sachDto.NhaXuatBang = sach.NhaXuatBang;
                sachDto.TacGia = sach.TacGia;
                sachDto.TenSach = sach.TenSach;
                sachDto.TheLoaiSach = sach.TheLoaiSach.TenTheLoaiSach;
                return sachDto;
            }
            catch
            {
                return null;
            }
        }

        [WebMethod]
        public SachDTO[] TimSachTheoTen(String sID, String tenSach)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                try
                {
                    List<Sach> dsSach =  dataBaseEntities
                                        .Saches
                                        .Where(s => s.TenSach.CompareTo(tenSach) == 0)
                                        .ToList();
                    List<SachDTO> sachTimThay = new List<SachDTO>();
                    foreach (Sach sach in dsSach)
                    {
                        SachDTO sachDto = new SachDTO();
                        sachDto.ConLai = (int)sach.SoLuongCon;
                        sachDto.GiaSach = (decimal)sach.GiaSach;
                        sachDto.LinkBiaSach = sach.AnhBia;
                        sachDto.MoTa = sach.TomTacNoiDung;
                        sachDto.NgayXuatBang = (DateTime)sach.NgayXuatBang;
                        sachDto.NhaXuatBang = sach.NhaXuatBang;
                        sachDto.TacGia = sach.TacGia;
                        sachDto.TenSach = sach.TenSach;
                        sachDto.TheLoaiSach = sach.TheLoaiSach.TenTheLoaiSach;
                        sachTimThay.Add(sachDto);
                    }
                    return sachTimThay.ToArray();
                }
                catch(Exception ex)
                {
                    return null;
                }
            }
            return null;

        }

        [WebMethod]
        public SachDTO TimSachTheoMa(String sID, int maSach)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                try
                {
                    Sach sach = dataBaseEntities
                        .Saches
                        .Where(s => s.MaSach == maSach)
                        .Single();
                   
                    SachDTO sachDto = new SachDTO();
                    sachDto.ConLai = (int)sach.SoLuongCon;
                    sachDto.GiaSach = (decimal)sach.GiaSach;
                    sachDto.LinkBiaSach = sach.AnhBia;
                    sachDto.MoTa = sach.TomTacNoiDung;
                    sachDto.NgayXuatBang = (DateTime)sach.NgayXuatBang;
                    sachDto.NhaXuatBang = sach.NhaXuatBang;
                    sachDto.TacGia = sach.TacGia;
                    sachDto.TenSach = sach.TenSach;
                    sachDto.TheLoaiSach = sach.TheLoaiSach.TenTheLoaiSach;
                    return sachDto;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
            return null;
        }

        [WebMethod]
        public int DatMua(String sID, int maSach, int soLuong)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                return session.GioHang.ThemSach(maSach, soLuong, sID);
            }
            else
            {
                return WsMessage.LOGIN_FAIL;
            }
            
        }

        [WebMethod]
        public string XemPhieuMua(String sID)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                string html = "";
                html += "<table>";
                html += "<tr><td>Tên Sách</td><td>Giá</td><td>Số Lượng</td><td>Thành Tiền</td></tr>";
                foreach (SachTrongGio stg in session.GioHang.DanhSachSach)
                {
                    SachDTO sach = LayThongTinSach(stg.MaSach);
                    html += "<tr>";
                    html += "<td>" + sach.TenSach +"</td>";
                    html += "<td>" + stg.DonGia + "</td>";
                    html += "<td>" + stg.SoLuong + "</td>";
                    html += "<td>" + (stg.DonGia * stg.SoLuong).ToString() + " đồng </td>";
                    html += "</tr>";
                }
                html += "<tr><td colspan='3'>Tổng thành tiền</td><td>" + session.GioHang.TinhTongTien() +" đồng </td></tr>";
                html += "</table>";
                return html;
            }
            else
            {
                return null;
            }

        }

        [WebMethod]
        public decimal ThanhToan(String sID)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                try
                {
                    HoaDon hoaDon = new HoaDon();
                    hoaDon.DaThanhToan = 0;
                    hoaDon.MaKhachHang = session.MaKhachHang;
                    hoaDon.NgayLapHoaDon = DateTime.Now;
                    hoaDon.ChiTietHoaDons = new System.Data.Objects.DataClasses.EntityCollection<ChiTietHoaDon>();
                    foreach (SachTrongGio stg in session.GioHang.DanhSachSach)
                    {
                        ChiTietHoaDon chiTietHoaDon = new ChiTietHoaDon();
                        chiTietHoaDon.MaSach = stg.MaSach;
                        chiTietHoaDon.SoLuong = stg.SoLuong;
                        chiTietHoaDon.DonGia = stg.DonGia;
                        chiTietHoaDon.ThanhTien = stg.SoLuong * stg.DonGia;
                        hoaDon.ChiTietHoaDons.Add(chiTietHoaDon);
                    }
                    hoaDon.TongThanhTien = session.GioHang.TinhTongTien();
                    dataBaseEntities.HoaDons.AddObject(hoaDon);
                    dataBaseEntities.SaveChanges();
                    foreach (ChiTietHoaDon cthd in hoaDon.ChiTietHoaDons)
                    {
                        cthd.Sach.SoLuongCon -= cthd.SoLuong;
                    }
                    dataBaseEntities.SaveChanges();
                    session.GioHang = new GioHang();
                    return (decimal)hoaDon.TongThanhTien;
                }
                catch
                {
                    return WsMessage.ERROR;
                }
            }
            else
            {
                return WsMessage.LOGIN_FAIL;
            }
        }


       
        private void ThemSession(int acountID, string sessionID)
        {
            Session session = new Session();
            session.sID = sessionID;
            session.MaKhachHang = acountID;
            session.LanTruyCapCuoi = DateTime.Now;
            dataBaseEntities.Sessions.AddObject(session);
            dataBaseEntities.SaveChanges();
        }
        
        
        private SessionInfo LaySession(string sID)
        {
            try
            {
                HuySessionQuaHan();
                Session curSession = dataBaseEntities
                        .Sessions.Where(s => s.sID.CompareTo(sID) == 0).Single();
                curSession.LanTruyCapCuoi = DateTime.Now;
                dataBaseEntities.SaveChanges();
                SessionInfo sessionInfo = new SessionInfo(curSession.sID, curSession.MaKhachHang, curSession.LanTruyCapCuoi);
                return sessionInfo;
            }
            catch (Exception)
            {

                return null;
            }
            
        }


        private void HuySessionQuaHan()
        {
            List<Session> sessionExp = dataBaseEntities
                .Sessions.ToList();
            foreach (var session in sessionExp)
            {
                if ((DateTime.Now - session.LanTruyCapCuoi).Minutes > 5)
                {
                    foreach (PhieuMua pm in session.PhieuMuas.ToList())
                    {
                        dataBaseEntities.PhieuMuas.DeleteObject(pm);
                    }
                    dataBaseEntities.Sessions.DeleteObject(session);
                }
                dataBaseEntities.SaveChanges();
            }
        }
        [WebMethod]
        public string ThongTinWs(string sID)
        {
            return "NXB The Duc The Thao - Nhom KD10 - Ver1.0";
        }

        [WebMethod]
        public TheLoaiDTO[] LayDanhSachTheLoai(string sID)
        {
            SessionInfo session = LaySession(sID);
            if (session != null)
            {
                List<TheLoaiSach> dsTheLoai = dataBaseEntities
               .TheLoaiSaches.ToList();
                List<TheLoaiDTO> kq = new List<TheLoaiDTO>();
                foreach (TheLoaiSach theLoaiSach in dsTheLoai)
                {
                    TheLoaiDTO tl = new TheLoaiDTO();
                    tl.TenTheLoai = theLoaiSach.TenTheLoaiSach;
                    tl.MaTheLoai = theLoaiSach.MaTheLoaiSach;
                    kq.Add(tl);
                }
                return kq.ToArray();
            }

            return null;
        }

        [WebMethod]
        public SachDTO[] LaySachTheoTheLoai(string sID, int maTheLoai)
        {
            SessionInfo session = LaySession(sID);
            if (session == null)
                return null;

            try
            {
                List<SachDTO> kq = new List<SachDTO>();
                List<Sach> sachs = dataBaseEntities
                    .Saches.Where(s => s.MaTheLoaiSach == maTheLoai)
                    .ToList();
                foreach (Sach sach in sachs)
                {
                    SachDTO ttSach = LayThongTinSach(sach.MaSach);
                    kq.Add(ttSach);
                }
                return kq.ToArray();
            }
            catch (Exception)
            {
                return null;
            }
        }

        [WebMethod]
        public SachDTO[] LayTatCaSach(string sID)
        {
            SessionInfo session = LaySession(sID);
            if (session == null)
                return null;

            try
            {
                List<SachDTO> kq = new List<SachDTO>();
                List<Sach> sachs = dataBaseEntities
                    .Saches.ToList();
                foreach (Sach sach in sachs)
                {
                    SachDTO ttSach = LayThongTinSach(sach.MaSach);
                    kq.Add(ttSach);
                }
                return kq.ToArray();
            }
            catch (Exception)
            {
                return null;
            }
        }

        [WebMethod]
        public int HuyPhieuMua(string sID)
        {
            SessionInfo session = LaySession(sID);
            if (session == null)
                return WsMessage.LOGIN_FAIL;

            session.HuyGioHang();
            return WsMessage.OK;
        }

        [WebMethod]
        public int DangXuat(string sID)
        {
            try
            {
                Session session = dataBaseEntities
                    .Sessions.Where(s => s.sID == sID).Single();
                dataBaseEntities.Sessions.DeleteObject(session);
                dataBaseEntities.SaveChanges();
                return WsMessage.OK;
            }
            catch (Exception)
            {
                return WsMessage.ERROR;
            }
        }
    }
}